#include "ohos_init.h" // 用于初始化服务(services)和功能(features)
#include "cmsis_os2.h" // CMSIS-RTOS API V2

#include "iota_payload.h"
#include  "bmsinfo.h"
#include "cJSON.h"
#include "hw_type.h"
#include "mqtt_client_entry.h"


static char strbuff[64];

/**
 * @brief 
 * 
 * @param device_info_report 
 * @return char* 
 */
char *IOTA_ReportBmsInfoPayload(ST_IOTA_DEVICE_INFO_REPORT *device_info_report)
{

    _SystemDataStru *bmsInf = getBmsInf();
    
    St_ListIotKey* p_listkey = getmListKey();

    if (device_info_report == NULL) {
        DebugMsg("[] IOTA_GetFileUrl: download or filename must not be none! ");
        return NULL;
    }
    cJSON *root = cJSON_CreateObject();
    cJSON *services = cJSON_CreateArray();
    cJSON *serviceEvent = cJSON_CreateObject();
    
    cJSON_AddStringToObject(root, OBJECT_DEVICE_ID, device_info_report->object_device_id);
    cJSON_AddStringToObject(serviceEvent, SERVICE_ID, IOT_SERVICEID_NAME);
    cJSON_AddStringToObject(serviceEvent, EVENT_TIME, device_info_report->event_time);

    cJSON *paras = cJSON_CreateObject();

    for(int32_t i = 0; i < getSizeOfListKey(); i ++)
    {
        if (p_listkey[i].key == NULL)   break;
        memset(strbuff, 0, sizeof(strbuff));
        
        switch (p_listkey[i].type)
        {
        case UINT32_DATA:
            {
                uint32_t* p_u32value = p_listkey[i].p_value;
                // if (p_listkey[i].f_str == TYPE_STR)
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_u32value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
                // else
                // {
                //     cJSON_AddNumberToObject(paras, p_listkey[i].key, *p_u32value);
                // }
            }
            break;
        case INT32_DATA:
            {
                int32_t* p_i32value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_i32value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case UINT16_DATA:
            {
                uint16_t* p_u16value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_u16value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case INT16_DATA:
            {
                int16_t* p_i16value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_i16value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case UINT8_DATA:
            {
                uint8_t* p_u8value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_u8value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case INT8_DATA:
            {
                int8_t* p_i8value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_i8value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case FLOAT_DATA:
            {
                float* p_fvalue = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%02.02f", *p_fvalue);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case U8_I8_DATA:
            {
                uint16_t* p_u16value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d-%d", (*p_u16value >> 8) & 0xFF, (*p_u16value & 0xFF));
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;

        default:
            break;
        }
    }
    
    // snprintf(strbuff, sizeof(strbuff), "%s", get_DateTimeString());
    // DebugMsg("[long] json point -> DateTime : %s\n", strbuff);
    // cJSON_AddStringToObject(paras, "DateTime", strbuff);
    cJSON_AddStringToObject(paras, "DateTime", "2024-12-12 12:00:00");
                
    // memset(str, 0, sizeof(str));
    // snprintf(str, sizeof(str), "%d", bmsInf->SysParamStru.HwVer);
    // cJSON_AddStringToObject(paras, IOT_HW_VERSION, str);

    if (device_info_report->device_ip != NULL) {
        cJSON_AddStringToObject(paras, DEVICE_IP, device_info_report->device_ip);
    }

    cJSON_AddItemToObject(serviceEvent, PROPERTIES, paras);
    cJSON_AddItemToArray(services, serviceEvent);
    cJSON_AddItemToObject(root, STR_SERVICE, services);

    // char *payload = cJSON_Print(root); // 呈现为JSON格式
    char *payload = cJSON_PrintUnformatted(root); // 呈现为无格式
    cJSON_Delete(root);
    return payload;
}



/**
 * @brief
 *
 * @param device_info_report
 * @return char*
 */
char *IOTA_ReportBmsInfoTabIndex(ST_IOTA_DEVICE_INFO_REPORT *device_info_report, uint32_t index)
{

    St_ListIotKey* p_listkey = getmListKey();

    if (device_info_report == NULL) {
        DebugMsg("IOTA_GetFileUrl: download or filename must not be none!");
        return NULL;
    }
    cJSON *root = cJSON_CreateObject();
    cJSON *services = cJSON_CreateArray();
    cJSON *serviceEvent = cJSON_CreateObject();

    cJSON_AddStringToObject(root, OBJECT_DEVICE_ID, device_info_report->object_device_id);
    cJSON_AddStringToObject(serviceEvent, SERVICE_ID, IOT_SERVICEID_NAME);
    cJSON_AddStringToObject(serviceEvent, EVENT_TIME, device_info_report->event_time);

    cJSON *paras = cJSON_CreateObject();

    int32_t i = index;
    {
        if ((p_listkey[i].key == NULL) || (i > getSizeOfListKey()))
        {
            return NULL;
        }
        memset(strbuff, '\0', sizeof(strbuff));

        switch (p_listkey[i].type)
        {
        case UINT32_DATA:
            {
                uint32_t* p_u32value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_u32value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case INT32_DATA:
            {
                int32_t* p_i32value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_i32value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case UINT16_DATA:
            {
                uint16_t* p_u16value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_u16value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case INT16_DATA:
            {
                int16_t* p_i16value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_i16value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case UINT8_DATA:
            {
                uint8_t* p_u8value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_u8value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case INT8_DATA:
            {
                int8_t* p_i8value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d", *p_i8value);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case FLOAT_DATA:
            {
                float* p_fvalue = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%02.02f", *p_fvalue);
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;
        case U8_I8_DATA:
            {
                uint16_t* p_u16value = p_listkey[i].p_value;
                {
                    snprintf(strbuff, sizeof(strbuff), "%d-%d", (*p_u16value >> 8) & 0xFF, (*p_u16value & 0xFF));
                    cJSON_AddStringToObject(paras, p_listkey[i].key, strbuff);
                }
            }
            break;

        default:
            break;
        }
//        DebugMsg("[long] index %d -> %s\n", i, strbuff);
    }

#if 0
    memset(strbuff, '\0', sizeof(strbuff));
    char* p_timeStr = dev_datetime_get_time();
//    DebugMsg("[long] buffer size = %d  str size = %d\n", sizeof(strbuff), sizeof(p_timeStr));
    sprintf(strbuff, "%s", p_timeStr);
//    DebugMsg("[long] json point -> DateTime : %s\n", strbuff);
//    DebugMsg("[long] p_timeStr -> DateTime : %s\n", p_timeStr);
    cJSON_AddStringToObject(paras, "DateTime", strbuff);
#endif
    cJSON_AddStringToObject(paras, "DateTime", "2024-12-12 12:00:00");

    if (device_info_report->device_ip != NULL) {
        cJSON_AddStringToObject(paras, DEVICE_IP, device_info_report->device_ip);
    }

    cJSON_AddItemToObject(serviceEvent, PROPERTIES, paras);
    cJSON_AddItemToArray(services, serviceEvent);
    cJSON_AddItemToObject(root, STR_SERVICE, services);

//    char *payload = cJSON_Print(root); // 呈现为JSON格式
    char *payload = cJSON_PrintUnformatted(root); // 呈现为无格式
//    DebugMsg("[long] json : %s\n", payload);
    cJSON_Delete(root);
    return payload;
}


void mqtt_SubTaskHandle(void *arg)
{
    (void)arg;

    MqttTaskSubscribe(MQTT_SUBTOPIC_DOWN);
    MqttTaskSubscribe(MQTT_SUBTOPIC_SET);

}

// 入口函数
void MqttSubEntry(void)
{
    // 定义线程属性
    osThreadAttr_t attr;
    attr.name = "mqttSub";
    attr.stack_size = 2048;  
    attr.priority = osPriorityNormal;
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;

    // 创建线程
    if (osThreadNew(mqtt_SubTaskHandle, NULL, &attr) == NULL)
    {
        printf("[MqttSubEntry] Falied to create mqtt_SubTaskHandle ... \n");
    }
}

